package polaris

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"
	"sync/atomic"
	"time"

	"git.woa.com/polaris/polaris-go/v2/api"
	plog "git.woa.com/polaris/polaris-go/v2/pkg/log"
)

const logLevel = plog.InfoLog

var (
	addresses string
	joinPoint string
	namespace string
	service   string
	seconds   int
	slice     string
)

func initArgs() {
	flag.StringVar(&addresses, "addresses", "", "polaris default addresses")
	flag.StringVar(&joinPoint, "joinPoint", "", "joinPoint")
	flag.StringVar(&namespace, "namespace", "", "namespace")
	flag.StringVar(&service, "service", "", "service")
	flag.IntVar(&seconds, "round", 1, "loop seconds")
	flag.StringVar(&slice, "slice", "", "slice name of service")
}

// 主入口函数
func server() {
	initArgs()
	flag.Parse()
	var err error
	err = api.ConfigLoggers("polaris", logLevel)
	if nil != err {
		log.Fatalf("fail to SetLogLevel, err is %v", err)
	}
	cfg := api.NewConfiguration()
	//创建consumerAPI实例
	//注意该实例所有方法都是协程安全，一般用户进程只需要创建一个consumerAPI,重复使用即可
	//切勿每次调用之前都创建一个consumerAPI
	//设置直接埋点地址与设置jointPoint不能同时生效
	if len(addresses) > 0 {
		cfg.GetGlobal().GetServerConnector().SetAddresses(strings.Split(addresses, ","))
	} else if len(joinPoint) > 0 {
		cfg.GetGlobal().GetServerConnector().SetJoinPoint(joinPoint)
	}
	consumer, err := api.NewConsumerAPIByConfig(cfg)
	if nil != err {
		log.Fatalf("fail to create ConsumerAPI by default configuration, err is %v", err)
	}
	defer consumer.Destroy()

	deadline := time.Now().Add(time.Duration(seconds) * time.Second)
	for {
		if time.Now().After(deadline) {
			break
		}
		var flowId uint64
		var getOneInstanceReq *api.GetOneInstanceRequest
		getOneInstanceReq = &api.GetOneInstanceRequest{}
		getOneInstanceReq.FlowID = atomic.AddUint64(&flowId, 1)
		getOneInstanceReq.Namespace = namespace
		getOneInstanceReq.Service = service
		//设置负载均衡算法为权重随机
		getOneInstanceReq.LbPolicy = api.LBPolicyWeightedRandom
		//设置服务的分片名
		getOneInstanceReq.SetSlice(slice)
		//假如用户需要使用规则路由等能力，则可以在这里通过SourceService属性设置主调服务的过滤标签
		//getOneInstanceReq.SourceService = &model.ServiceInfo{
		//	Namespace: "Development",
		//	Service:   "trpc.fcgi.FcgiOnBoardServer.x",
		//	Metadata: map[string]string{
		//		"env": "32d4ffcd",
		//	},
		//}
		startTime := time.Now()
		//进行服务发现，获取单一服务实例
		getInstResp, err := consumer.GetOneInstance(getOneInstanceReq)
		if nil != err {
			log.Fatalf("fail to sync GetOneInstance, err is %v", err)
		}
		consumeDuration := time.Since(startTime)
		log.Printf("success to sync GetOneInstance, count is %d, consume is %v\n",
			len(getInstResp.Instances), consumeDuration)
		targetInstance := getInstResp.Instances[0]
		log.Printf("sync instance is id=%s, address=%s:%d\n",
			targetInstance.GetId(), targetInstance.GetHost(), targetInstance.GetPort())

		resp, err := http.Get(fmt.Sprintf("http://%s:%d", targetInstance.GetHost(), targetInstance.GetPort()))
		if nil != err {
			log.Fatalf("fail to http.Get, err is %v", err)
		}

		data, err := io.ReadAll(resp.Body)
		if err != nil {
			log.Fatalf("fail to ReadAll, err is %v", err)
		}
		err = json.Unmarshal(data, &Response{})
		if err != nil {
			log.Fatalf("fail to Unmarshal, err is %v", err)
		}
		fmt.Println(string(data))
		//构造请求，进行服务调用结果上报
		svcCallResult := &api.ServiceCallResult{}
		//设置被调的实例信息
		svcCallResult.SetCalledInstance(targetInstance)
		//设置服务调用结果，枚举，成功或者失败
		svcCallResult.SetRetStatus(api.RetSuccess)
		//设置服务调用返回码
		svcCallResult.SetRetCode(0)
		//设置服务调用时延信息
		svcCallResult.SetDelay(consumeDuration)
		//执行调用结果上报
		err = consumer.UpdateServiceCallResult(svcCallResult)
		if nil != err {
			log.Fatalf("fail to UpdateServiceCallResult, err is %v", err)
		}
		time.Sleep(1 * time.Second)
	}
	log.Printf("success to sync get one instance")

}

type User struct {
	ID    int    `json:"id"`
	Name  string `json:"name"`
	Email string `json:"email"`
}

type Response struct {
	Users  []User `json:"users"`
	Status int    `json:"status"`
}
